package com.sunday.common.core.remoting.rpc.response;

import com.sunday.common.core.remoting.base.response.ExceptionResponse;
import com.sunday.common.core.remoting.base.response.Response;
import com.sunday.common.core.remoting.base.response.ResponseHandler;
import com.sunday.common.core.remoting.base.response.core.MethodCallback;
import com.sunday.common.core.remoting.base.response.core.ThrowableFilter;
import org.springframework.lang.Nullable;

/**
 * RPC 异常处理器
 *
 * @author zsy
 * @since 2022/10/14
 */
public class RPCResponseHandler {

    public static <K> Response<K> invoke(MethodCallback<Response<K>> callback) {
        return invoke(callback, null);
    }

    public static <K> Response<K> invoke(MethodCallback<Response<K>> callback, @Nullable ThrowableFilter filter) {
        return ResponseHandler.invoke(() -> callback.doWith(), ExceptionResponse.RPC_RESPONSE_RESOLVE, filter);
    }

    /**
     * 泛型与语法糖真的是即爱又恨，很多时候我们依赖与语法糖的便利，泛型的有效类型指示进行编码，但是其中存在了原生语法的补全，导致只有操作时才会报错
     * 而本次要说的是另外一个问题，就是内部转换的强转补偿
     * 举个例子
     *         Response<PageResultDTO<PageBlacklistLibraryResDTO>> response = Response.ok(PageResultDTO.of(1,10));
     *         RPCResponseHandler.invoke(() -> response).getBody();
     * 当使用如下方法封装时
     *     public static <K> Response<K> invoke(ResponseHandler.MethodCallback<Response<K>> callback, @Nullable ResponseHandler.ThrowableFilter filter) {
     *         return ResponseHandler.invoke(callback, ExceptionResponse.RPC_RESPONSE_RESOLVE ,filter);
     *     }
     * 就会产生一个问题
     * 其中 callback和 resolve 均由 public interface MethodCallback<T> 和  public interface ExceptionResolve<T> 封装
     * 而当前方法中 ResponseHandler.MethodCallback<Response<K>> callback 导致与 ExceptionResponse.RPC_RESPONSE_RESOLVE 中定义<T> 冲突
     * 所以需要额外在包裹一层，来使泛型统一
     *     public static <K> Response<K> invoke(ResponseHandler.MethodCallback<Response<K>> callback, @Nullable ResponseHandler.ThrowableFilter filter) {
     *         return ResponseHandler.invoke(() -> callback.doWith(), ExceptionResponse.RPC_RESPONSE_RESOLVE ,filter);
     *     }
     *  class解析为：
     *    public static <K> Response<K> invoke(MethodCallback<Response<K>> callback, @Nullable ThrowableFilter filter) {
     *         return (Response)ResponseHandler.invoke(() -> {
     *             return (Response)callback.doWith();
     *         }, ExceptionResponse.RPC_RESPONSE_RESOLVE, filter);
     *     }
     *
     *   可以看到为了整体统一，语法糖在编译class使，进行了一次强制转换来保持与 ExceptionResponse.RPC_RESPONSE_RESOLVE 的类型统一，
     *   这样整体就达到了类型一致，并且返回类型也会按照
     *   public static <K> Response<K> invoke(MethodCallback<Response<K>> callback, @Nullable ThrowableFilter filter) 这样的要求，形成类型提示。
     */


}
